﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using XLua;

/// <summary>
/// 这个是脚本是最先执行的
/// </summary>
public class GameInit : MonoBehaviour
{
    public Action LoadOverAction;
    private string downloadPath;
    //lua中要使用到C#库的配置，比如C#标准库，或者Unity API，第三方库等。
    void Awake()
    {
        downloadPath = PathUtil.GetAssetBundleOutPath();
        LoadOverAction = () => {
            //开始游戏主逻辑
            //todo 资源下载结束后,添加LuaManager,AssetBundleManager，加载相关资源
            gameObject.AddComponent<LuaManager>();
            gameObject.AddComponent<AssetBundleManager>();

            //Resouces文件夹方式执行lua文件
            LuaManager._instance.DoString("require 'LGameInit'");
            print("执行lua脚本");
            LuaManager._instance.CallLuaFunction("LGameInit", "init");
            print("执行完毕");
        };
        // 检测资源进行比对更新
        StartCoroutine(downloadRes(LoadOverAction));
    }


    /// <summary>
    ///  检测资源进行比对更新 (模拟测试 本机 用)
    /// </summary>
    private IEnumerator downloadRes4Test()
    {
        //此处应该是下载url  网址:端口号:路径  "http://127.0.0.1:6666/path/"
        string url = "E:/LuaServer";

        //此处是文件路径
        string fileUrl = url + "/files.txt";

        //判断本地有没有这个目录
        //如果发布到手机上： 游戏一运行 就把 streamingAssetsPath 的文件 拷贝到 persistentDataPath 路径下
        if (!Directory.Exists(downloadPath))
            Directory.CreateDirectory(downloadPath);

        //读取里面的内容
        string[] lines = File.ReadAllLines(fileUrl);

        for (int i = 0; i < lines.Length; i++)
        {
            if (string.IsNullOrEmpty(lines[i]))
                continue;

            string[] kv = lines[i].Split('|');
            string fileName = kv[0];
            //再拿到本地的这个文件
            string localFile = (downloadPath + "/" + fileName).Trim();
            //如果本地文件没有 需要下载了
            if (!File.Exists(localFile))
            {
                //Debug.Log("本地没有 " + fileName + " 去服务器下载了");
                string dir = Path.GetDirectoryName(localFile);
                Directory.CreateDirectory(dir);

                string tmpUrl = url + "/" + fileName;
                //开始网络下载
                if (fileName[0] == 'L')
                {
                    //Lua脚本文件，用文本方式下载
                    string tmpText = File.ReadAllText(tmpUrl);
                    File.WriteAllText(localFile, tmpText);
                }
                else
                {
                    //AB包，用Byte方式下载
                    byte[] tmpBytes = File.ReadAllBytes(tmpUrl);
                    File.WriteAllBytes(localFile, tmpBytes);
                }
            }
            else //如果文件有  开始比对md5 作用：检测是否更新了
            {
                string md5 = kv[1];
                string localMd5 = getFileMd5(localFile);
                if (md5 == localMd5)
                {
                    //如果 md5 一样的话，那么就没更新 
                    //Debug.Log("本地有 " + fileName + " 而且没更新");
                }
                else
                {
                    //Debug.Log("本地有" + fileName + " 但是更新了 去服务器下载了");
                    //如果不一样的话 说明更新了 
                    //删除本地原来的旧文件
                    File.Delete(localFile);
                    //下载新文件
                    string tmpUrl = url + "/" + fileName;
                    if (fileName[0] == 'L')
                    {
                        //Lua脚本文件以L开头，用文本方式下载
                        string tmpText = File.ReadAllText(tmpUrl);
                        File.WriteAllText(localFile, tmpText);
                    }
                    else
                    {
                        //AB包，用Byte方式下载
                        byte[] tmpBytes = File.ReadAllBytes(tmpUrl);
                        File.WriteAllBytes(localFile, tmpBytes);
                    }
                }
            }
        }
        yield return new WaitForEndOfFrame();

        Debug.Log("更新完成，可以开始游戏了");
    }


    /// <summary>
    ///  检测资源进行比对更新(网络下载)
    /// </summary>
    private IEnumerator downloadRes(Action OverAction)
    {
        //这里是资源下载地址
        string url = "http://192.168.35.248:5676/";
        //下载MD5校验文件
        string fileUrl = url + "files.txt";
        WWW www = new WWW(fileUrl);
        print("1开始下载files.txt");
        yield return www;
        print("2开始下载files.txt");
        //进行一些网络的检测
        if (www.error != null)
            Debug.LogError(www.error);

        //判断本地有没有这个目录，没有则创建一个路径
        //如果发布到手机上： 游戏一运行 就把 streamingAssetsPath 的文件 拷贝到 persistentDataPath 路径下
        if (!Directory.Exists(downloadPath))
            Directory.CreateDirectory(downloadPath);

        //就会把下载的md5校验文件写入本地
        File.WriteAllBytes(downloadPath + "/files.txt", www.bytes);

        //读取里面的内容
        string filesText = www.text;
        string[] lines = filesText.Split('\n');

        print("开始校验md5");
        //遍历files文件，逐个检测是否需要更新
        for (int i = 0; i < lines.Length; i++)
        {
            if (string.IsNullOrEmpty(lines[i]))
                continue;

            string[] kv = lines[i].Split('|');
            //拿到文件名
            string fileName = kv[0];
            //再拿到本地的这个文件路径，去除空格
            string localFile = (downloadPath + "/" + fileName).Trim();
            //如果本地文件没有 需要下载了，不用检测md5
            if (!File.Exists(localFile))
            {
                //获取文件夹的名字
                string dir = Path.GetDirectoryName(localFile);
                Directory.CreateDirectory(dir);

                //开始网络下载
                string tmpUrl = url + fileName;
                www = new WWW(tmpUrl);
                yield return www;
                //进行一些网络的检测
                if (www.error != null)
                    Debug.LogError(www.error);
                if (fileName[0] == 'L')
                {
                    //Lua脚本文件以L开头，用文本方式下载
                    File.WriteAllText(localFile, www.text);
                }
                else
                {
                    //AB包，用Byte方式下载
                    File.WriteAllBytes(localFile, www.bytes);
                }
            }
            else //如果文件有  开始比对md5 作用：检测是否更新了
            {
                string md5 = kv[1];
                string localMd5 = getFileMd5(localFile);
                if (md5 == localMd5)
                {
                    //如果 md5 一样的话，那么就不用更新 
                }
                else
                {
                    //如果不一样的话 说明需要更新 
                    //删除本地原来的旧文件  
                    File.Delete(localFile);
                    //下载新文件
                    string tmpUrl = url + fileName;
                    www = new WWW(tmpUrl);
                    yield return www;
                    //进行一些网络的检测
                    if (www.error != null)
                        Debug.LogError(www.error);
                    if (fileName[0] == 'L')
                    {
                        //Lua脚本文件以L开头，用文本方式下载
                        File.WriteAllText(localFile, www.text);
                    }
                    else
                    {
                        //AB包，用Byte方式下载
                        File.WriteAllBytes(localFile, www.bytes);
                    }
                }
            }
        }
        yield return new WaitForEndOfFrame();

        Debug.Log("下载结束，开始加载相关资源");
        if (OverAction != null)
            OverAction();
    }

    /// <summary>
    /// 获取文件的md5值
    /// </summary>
    /// <param name="filePath"></param>
    private string getFileMd5(string filePath)
    {
        FileStream fs = new FileStream(filePath, FileMode.Open);
        MD5 md5 = new MD5CryptoServiceProvider();

        byte[] result = md5.ComputeHash(fs);
        fs.Close();

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < result.Length; i++)
        {
            sb.Append(result[i].ToString("x2"));
        }
        return sb.ToString();
    }

}
